/*
 * graph.cpp
 *
 *  Created on: 10.10.2011
 *      Author: duke
 */

#include <iostream>
#include <vector>
#include <iterator>
#include "graph.h"

using namespace std;

graph::graph() {
}

graph::graph(dynamic_array adj) {
	this->adjacency = adj;
	for (int i = 0; i < this->adjacency.getrows(); i++) {
		for (int j = 0; j <= i; j++) {
			if (adj[i][j] == 1) {
				this->edges.push_back(edge(i, j));
			}
		}
	}
}

/*graph(vector<edge> edges) {
 dynamic_array temp(edges.size(), edges.size());
 this->edges = edges;
 int node1, node2;
 for (vector<edge>::iterator it = edges.begin(); it != edges.end(); ++it) {
 node1 = it->getNode1();
 node2 = it->getNode2();
 temp[node1][node2] = 1;
 }
 this->adjacency = temp;
 }*/

int graph::numOfEdges() {
	return this->edges.size();
}

vector<edge> graph::getAllEdges() {
	return this->edges;
}

bool graph::isTriangleFree(int max = 0) {
	int a0, a1, b0, b1, c0, c1;
	if (max < 0)
		return true;
	if (max == 0)
		max = this->edges.size();
	else
		max = 1;
	int i, j, k;
	for (i = 0; i < max; i++) {
		for (j = i + 1; j < max; j++) {
			for (k = j + 1; k < max; k++) {
				a0 = this->edges[i].getNode1();
				a1 = this->edges[i].getNode2();
				b0 = this->edges[j].getNode1();
				b1 = this->edges[j].getNode2();
				c0 = this->edges[k].getNode1();
				c1 = this->edges[k].getNode2();
				//cout << a0 << a1 << b0 << b1 << c0 << c1 << endl;
				if ((a0 == b0 && a1 == c0 && b1 == c1) || (a0 == c0 && a1 == b0
						&& b1 == c1) || (a0 == b0 && a1 == c0 && a1 == c1)
						|| (a0 == c0 && a1 == b1 && b0 == c1) || (a0 == b1
						&& a1 == c1 && b0 == c0) || (a0 == c1 && a1 == b1 && b0
						== c0)) {
					//cout << "triangle " << endl;
					return false;
				}
			}
		}
	}
	return true;
	/*if (max == 0)
	 max = size;
	 int node1, node2, biggest_node = 0, i = 0;
	 for (vector<edge>::iterator it = edges.begin(); it != edges.end(); it++) {
	 node1 = it->getNode1();
	 node2 = it->getNode2();
	 if (node1 > biggest_node) {
	 biggest_node = node1;
	 }
	 if (node2 > biggest_node) {
	 biggest_node = node2;
	 }
	 i++;
	 if (i > max)
	 break;
	 }
	 //cout << "i=" << i  << ", max=" << max << ", biggest=" << biggest_node << endl;
	 dynamic_array temp(biggest_node + 1, biggest_node + 1);
	 i = 0;
	 for (vector<edge>::iterator it = edges.begin(); it != edges.end(); it++) {
	 node1 = it->getNode1();
	 node2 = it->getNode2();
	 temp[node1][node2] = 1;
	 temp[node2][node1] = 1;
	 i++;
	 if (i > max)
	 break;
	 }
	 temp.print();
	 //dynamic_array temp(size, size);
	 //temp = this->adjacency * this->adjacency * this->adjacency;
	 //temp.print();
	 temp = temp * temp * temp;
	 for (int i = 0; i < biggest_node + 1; i++) {
	 if (temp[i][i] != 0)
	 return false;
	 }
	 return true;*/
}

vector<edge> graph::getEdges(int color) {
	vector<edge> temp;
	for (vector<edge>::iterator it = this->edges.begin(); it
			!= this->edges.end(); ++it) {
		if (it->getColor() == color)
			temp.push_back(*it);
	}
	return temp;
}

void graph::setEdges(vector<edge> edges) {
	this->edges = edges;
	int node1, node2, biggest_node = 0;
	for (vector<edge>::iterator it = edges.begin(); it != edges.end(); it++) {
		node1 = it->getNode1();
		node2 = it->getNode2();
		if (node1 > biggest_node) {
			biggest_node = node1;
		}
		if (node2 > biggest_node) {
			biggest_node = node2;
		}
	}
	dynamic_array temp(biggest_node + 1, biggest_node + 1);
	for (vector<edge>::iterator it = edges.begin(); it != edges.end(); it++) {
		node1 = it->getNode1();
		node2 = it->getNode2();
		temp[node1][node2] = 1;
		temp[node2][node1] = 1;
	}
	this->adjacency = temp;
}

void graph::setEdges(stackitem st) {
	int node1, node2, biggest_node = 0;
	this->edges = st.getAllEdges();
	for (vector<edge>::iterator it = this->edges.begin(); it
			!= this->edges.end(); it++) {
		node1 = it->getNode1();
		node2 = it->getNode2();
		if (node1 > biggest_node) {
			biggest_node = node1;
		}
		if (node2 > biggest_node) {
			biggest_node = node2;
		}
	}
	dynamic_array temp(biggest_node + 1, biggest_node + 1);
	for (vector<edge>::iterator it = this->edges.begin(); it
			!= this->edges.end(); it++) {
		node1 = it->getNode1();
		node2 = it->getNode2();
		temp[node1][node2] = 1;
		temp[node2][node1] = 1;
	}
	this->adjacency = temp;
}

/*void graph::setEdges(int *buffer, int buff_length) {
 int node1, node2, biggest_node = 0;
 this->edges = st.getAllEdges();
 for (vector<edge>::iterator it = this->edges.begin(); it
 != this->edges.end(); it++) {
 node1 = it->getNode1();
 node2 = it->getNode2();
 if (node1 > biggest_node) {
 biggest_node = node1;
 }
 if (node2 > biggest_node) {
 biggest_node = node2;
 }
 }
 dynamic_array temp(biggest_node + 1, biggest_node + 1);
 for (vector<edge>::iterator it = this->edges.begin(); it
 != this->edges.end(); it++) {
 node1 = it->getNode1();
 node2 = it->getNode2();
 temp[node1][node2] = 1;
 temp[node2][node1] = 1;
 }
 this->adjacency = temp;
 }*/

void graph::setEdgeColor(int index, int color) {
	this->edges.at(index).setColor(color);
}

int graph::getEdgeColor(int index) {
	return this->edges.at(index).getColor();
}

int * graph::getArray() {
	int j = 0;
	int array_size = 2 + this->edges.size() * 3;
	int *temp = new int[array_size];
	temp[0] = 0;
	temp[1] = 0;
	for (int i = 2; i < array_size - 2; i++, j++) {
		temp[i++] = this->edges.at(j).getNode1();
		temp[i++] = this->edges.at(j).getNode2();
		temp[i] = this->edges.at(j).getColor();
	}
	return temp;
}

void graph::print() {
	cout << "# of edges: " << numOfEdges() << endl;
	cout << "edges:" << endl;
	if (this->edges.size()) {
		for (vector<edge>::iterator it = this->edges.begin(); it
				!= this->edges.end(); it++) {
			it->print();
		}
	} else
		cout << "none..." << endl;
}
